#include "bgmcontrol.h"
#include "Game_Control_Class/playhand.h"
#include "qaudiooutput.h"
#include <QFile>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QTimer>
#include <QDebug>

BgmControl::BgmControl(QObject *parent)
    : QObject{parent}
{
    for (int i = 0; i < 5; ++i) {
        QMediaPlayer* player = new QMediaPlayer(this);
        MediaPlayerList* list = new MediaPlayerList(this);
        QAudioOutput* audioOutput = new QAudioOutput(this);

        if (i < 2 || i == 4) {
            list->setPlaybackMode(MediaPlayerList::CurrentItemOnce);
        } else if (i == 2) {
            list->setPlaybackMode(MediaPlayerList::Loop);
        }

        player->setAudioOutput(audioOutput);
        audioOutput->setVolume(1);

        //checkAudioDevice();
        m_players.push_back(player);
        m_lists.push_back(list);
    }
    initPlayList();
}

void BgmControl::initPlayList()
{
    QStringList list;
    list << "Man" << "Woman" << "BGM" << "Other" << "Ending";

    // 读json配置文件
    QFile file(":/conf/playList.json");
    if (!file.open(QFile::ReadOnly)) {
        qWarning() << "Failed to open PlayList.json";
        return;
    }
    QByteArray json = file.readAll();
    //qDebug()<<json;
    file.close();

    // 解析从文件中读出的json数据
    QJsonDocument doc = QJsonDocument::fromJson(json);
    QJsonObject obj = doc.object();
    qDebug()<<obj["Man"];

    // 初始化多媒体播放列表
    for (int i = 0; i < list.size(); ++i) {
        QString prefix = list.at(i);
        QJsonArray array = obj.value(prefix).toArray();

        QList<QString> songPaths; // 使用 QList 存储歌曲路径
        for (int j = 0; j < array.size(); ++j) {
            QString path = array.at(j).toString();
            if (!path.startsWith("qrc:")) {
                path = "qrc:" + path; // 确保路径以 qrc: 开头
            }
            songPaths.append(path); // 按顺序添加到 QList
            qDebug() << "Song path:" << path;
        }

        // 将 QList 转换为 QVariantList
        QVariantList songList;
        for (const QString& path : songPaths) {
            QVariantMap song;
            song["path"] = path;
            songList.append(song);
        }

        m_lists[i]->setSongList(songList); // 设置播放列表
    }
}

void BgmControl::startBGM(int volume)
{
    //qDebug() << "BO";
    MediaPlayerList* list = m_lists[2];
    QString songPath = list->songAt(0); // 获取第一首歌曲路径

    qDebug()<<songPath;
    if (songPath.isEmpty()) {
        qWarning() << "Invalid song path!";
        return;
    }

    double vol=volume;
    QAudioOutput* audioOutput = new QAudioOutput(this);
    audioOutput->setVolume(vol/100); // 设置音量（范围：0.0 到 1.0）
    audioOutput->setMuted(false); // 确保未静音
    // 检查音频输出设置
    // qDebug() << "Audio output volume:" << audioOutput->volume();
    // qDebug() << "Audio output muted:" << audioOutput->isMuted();
    m_players[2]->setAudioOutput(audioOutput);
    m_players[2]->setSource(QUrl(songPath));
    m_players[2]->play();
    // 连接信号，实现循环播放
    connect(m_players[2], &QMediaPlayer::mediaStatusChanged, this, [this, list](QMediaPlayer::MediaStatus status) {
        if (status == QMediaPlayer::EndOfMedia) {
            QString nextSongPath = list->nextSong(); // 获取下一首歌曲路径
            if (!nextSongPath.isEmpty()) {
                m_players[2]->setSource(QUrl(nextSongPath));
                m_players[2]->play();
            } else {
                qWarning() << "No more songs in the playlist!";
            }
        }
    });

    //qDebug() << "B)1";
}

void BgmControl::stopBGM()
{
    m_players[2]->stop();
}

void BgmControl::playerRobLorMusic(int point, RoleSex sex, bool isFirst)
{
    int index = sex == Man ? 0 : 1;
    MediaPlayerList* list = m_lists[index];
    int trackIndex = 0;

    if (isFirst && point > 0) {
        trackIndex = Order;
    } else if (point == 0) {
        trackIndex = isFirst ? NoOrder : NoRob;
    } else if (point == 2) {
        trackIndex = Rob1;
    } else if (point == 3) {
        trackIndex = Rob2;
    }

    QString songPath = list->songAt(trackIndex);
    qDebug()<<trackIndex;
    qDebug()<<songPath;
    if (!songPath.isEmpty()) {
        m_players[index]->setSource(QUrl(songPath));
        m_players[index]->play();
    } else {
        qWarning() << "Invalid song path for track index:" << trackIndex;
    }
}

void BgmControl::playCardMusic(Cards cards, bool isFirst, RoleSex sex)
{
    int index = sex == Man ? 0 : 1;
    MediaPlayerList* list = m_lists[index];

    Card::CardPoint pt = Card::CardPoint::Point_Begin;
    PlayHand hand(cards);
    PlayHand::HandType type = hand.getHandType();
    if (type == PlayHand::Hand_Single || type == PlayHand::Hand_Pair || type == PlayHand::Hand_Triple) {
        pt = cards.takeRandCard().point();
    }

    int number = 0;
    switch (type) {
    case PlayHand::Hand_Single:
        number = pt - 1;
        break;
    case PlayHand::Hand_Pair:
        number = pt - 1 + 15;
        break;
    case PlayHand::Hand_Triple:
        number = pt - 1 + 15 + 13;
        break;
    case PlayHand::Hand_Triple_Single:
        number = ThreeBindOne;
        break;
    case PlayHand::Hand_Triple_Pair:
        number = ThreeBindPair;
        break;
    case PlayHand::Hand_Plane:
    case PlayHand::Hand_Plane_Two_Single:
    case PlayHand::Hand_Plane_Two_Pair:
        number = Plane;
        break;
    case PlayHand::Hand_Seq_Pair:
        number = SequencePair;
        break;
    case PlayHand::Hand_Seq_Single:
        number = Sequence;
        break;
    case PlayHand::Hand_Bomb:
        number = Bomb;
        break;
    case PlayHand::Hand_Bomb_Jokers:
        number = JokerBomb;
        break;
    case PlayHand::Hand_Bomb_Pair:
    case PlayHand::Hand_Bomb_Two_Single:
    case PlayHand::Hand_Bomb_Jokers_Pair:
    case PlayHand::Hand_Bomb_Jokers_Two_Single:
        number = FourBindTwo;
        break;
    default:
        break;
    }

    if (!isFirst && (number >= Plane && number <= FourBindTwo)) {
        number = MoreBiger1 + QRandomGenerator::global()->bounded(2);
    }

    QString songPath = list->songAt(number);
    if (!songPath.isEmpty()) {
        m_players[index]->setSource(QUrl(songPath));
        m_players[index]->play();
    } else {
        qWarning() << "Invalid song path for number:" << number;
    }

    if (number == Bomb || number == JokerBomb) {
        playAssistMusic(BombVoice);
    }
    if (number == Plane) {
        playAssistMusic(PlaneVoice);
    }
}

void BgmControl::playLastMusic(CardType type, RoleSex sex)
{
    int index = sex == Man ? 0 : 1;
    MediaPlayerList* list = m_lists[index];

    if (m_players[index]->playbackState() == QMediaPlayer::StoppedState) {
        QString songPath = list->songAt(type);
        m_players[index]->setSource(QUrl(songPath));
        m_players[index]->play();
    } else {
        QTimer::singleShot(1500, this, [=]() {
            QString songPath = list->songAt(type);
            m_players[index]->setSource(QUrl(songPath));
            m_players[index]->play();
        });
    }
}

void BgmControl::playPassMusic(RoleSex sex)
{
    int index = sex == Man ? 0 : 1;
    MediaPlayerList* list = m_lists[index];
    int random = QRandomGenerator::global()->bounded(4);
    QString songPath = list->songAt(Pass1 + random);

    if (!songPath.isEmpty()) {
        m_players[index]->setSource(QUrl(songPath));
        m_players[index]->play();
    } else {
        qWarning() << "Invalid song path for random index:" << random;
    }
}

void BgmControl::playAssistMusic(AssistMusic type)
{
    MediaPlayerList::PLAYBACK_MODE mode = (type == Dispatch) ? MediaPlayerList::CurrentItemInLoop : MediaPlayerList::CurrentItemOnce;
    MediaPlayerList* list = m_lists[3];

    list->setCurrentIndex(type);
    list->setPlaybackMode(mode);

    QString songPath = list->songAt(type);
    if (!songPath.isEmpty()) {
        m_players[3]->setSource(QUrl(songPath));
        m_players[3]->play();
    } else {
        qWarning() << "Invalid song path for AssistMusic type:" << type;
    }
}

void BgmControl::stopAssistMusic()
{
    m_players[3]->stop();
}

void BgmControl::playEndingMusic(bool isWin)
{
    MediaPlayerList* list = m_lists[4];
    QString songPath = list->songAt(isWin ? 0 : 1);

    if (!songPath.isEmpty()) {
        m_players[4]->setSource(QUrl(songPath));
        m_players[4]->play();
    } else {
        qWarning() << "Invalid song path for ending music:" << isWin;
    }
}

#include <QMediaDevices>
#include <QAudioDevice>

void BgmControl::checkAudioDevice()
{
    QAudioDevice defaultDevice = QMediaDevices::defaultAudioOutput();
    if (defaultDevice.isNull()) {
        qWarning() << "No default audio device found!";
    } else {
        qDebug() << "Default audio device:" << defaultDevice.description();
    }
}

void BgmControl::checkPlayerState(QMediaPlayer* player)
{
    if (player->playbackState() == QMediaPlayer::PlayingState) {
        qDebug() << "Player is playing";
    } else {
        qWarning() << "Player is not playing";
    }
}
